package BD;

import BE.Funcionalidad;
import BE.Usuario;
import BE.Usuarioventas;
import BE.Usuarioxrol;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import util.Logica;

/**
 *
 * @author marvil
 * @todo cambiar println's por log real
 */
public class UsuarioBD {

    Transaction tx = null;
    private Session session = null;

    public boolean eliminarUsuario(Usuario objUsuario) {
        tx = null;
        try {
            tx = session.beginTransaction();
            session = HibernateUtil.getSessionFactory().getCurrentSession();
            tx = (Transaction) session.beginTransaction();
            session.flush();
            session.evict(objUsuario);
            session.update(objUsuario);
            tx.commit();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            if (tx != null && tx.isActive()) {
                tx.rollback();
            }
            return false;
        }
    }
    public boolean insertarUsuarioxrol(Usuarioxrol objUsuarioxrol) {
        tx = null;
        try {
            session = HibernateUtil.getSessionFactory().getCurrentSession();
            tx = session.beginTransaction();
//            session.flush();
            session.evict(objUsuarioxrol);
            session.save(objUsuarioxrol);
            tx.commit();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            if (tx != null && tx.isActive()) {
                tx.rollback();
            }
            return false;
        }
    }

  public void borrarUsuariosRol(int intIdUsuario) {
        tx = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            tx = session.beginTransaction();
//            Criteria crit = session.createCriteria(Rol.class);
//Nombresss
            String hql = "delete from Usuarioxrol as u " +
                    " where upper u.Usuarioxrol.srlIdusuario =:intIdUsuario ";

            Query query = (Query) session.createQuery(hql);
            //indico que si algun campo es NULL, lo reemplaze por '%%' para el LIKE (recordar SQL)
            query.setInteger("intIdUsuario", intIdUsuario);
            session.flush();
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            if (tx != null && tx.isActive()) {
                tx.rollback();
            }
        }

    }
public List<Usuario> ObtenerUnUsuario(int idUsuario) {
        List<Usuario> lista = null;
        try {
            session = HibernateUtil.getSessionFactory().getCurrentSession();
            tx = session.beginTransaction();
            //p.nombre de la entidad
            String hql = "from Usuario as u" +
                    " where u.srlIdpersona= :idUsuario";

            //-1 representa "TODOS" en el JSP (revisar JSP) PD: no se me ocurrio otra forma de hacer esto

            Query query = session.createQuery(hql);
            query.setInteger("idUsuario", idUsuario);

            session.flush();
//            lista = crit.list();
            lista = query.list();
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            if (tx != null && tx.isActive()) {
                tx.rollback();
            }
        }
        return lista;
    }

 public int insertarUsuario(Usuario objUsuarioBE) {

        try {

            session = HibernateUtil.getSessionFactory().openSession();
            tx = (Transaction) session.beginTransaction();
            Serializable o = session.save(objUsuarioBE);

            tx.commit();

            return Integer.parseInt(o.toString());
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }

    }
 public boolean modificarUsuario(Usuario objUsuario) {

        try {

            tx = session.beginTransaction();
            session = HibernateUtil.getSessionFactory().openSession();
            tx = (Transaction) session.beginTransaction();
            session.flush();
            session.evict(objUsuario);

            Usuario objUsuarioX = (Usuario) session.get(Usuario.class, new Integer(objUsuario.getSrlIdpersona()));

            if (objUsuarioX == null) {

                objUsuarioX = new Usuario();
                objUsuarioX.setCvNombre(objUsuario.getCvNombre());
                objUsuarioX.setBoolEliminado(objUsuario.isBoolEliminado());

            }
            objUsuarioX.setCvNombre(objUsuario.getCvNombre());
            objUsuarioX.setCvApellidopaterno(objUsuario.getCvApellidopaterno());
            objUsuarioX.setCvApellidomaterno(objUsuario.getCvApellidomaterno());
            objUsuarioX.setCvEmail(objUsuario.getCvEmail());
            objUsuarioX.setCvEmail2(objUsuario.getCvEmail2());
            objUsuarioX.setCvTelefono1(objUsuario.getCvTelefono1());
            objUsuarioX.setCvTelefono2(objUsuario.getCvTelefono2());
            objUsuarioX.setCvDocumento(objUsuario.getCvDocumento());

            objUsuarioX.setBoolEliminado(objUsuario.isBoolEliminado());
            objUsuarioX.setBoolBloqueado(objUsuario.isBoolBloqueado());
            session.saveOrUpdate(objUsuarioX);
            tx.commit();
            //session.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
                if (tx != null && tx.isActive()) {
                tx.rollback();
            }
            return false;

        }
    }


    public List<Usuario> buscarUsuarioMant(Usuario objUsuario) {
        List<Usuario> lista = null;
        
               try {
            session = HibernateUtil.getSessionFactory().openSession();

            tx = session.beginTransaction();
//            Criteria crit = session.createCriteria(Rol.class);
//Nombresss
            String hql = "from Usuario as u " +
                    " where upper(u.cvNombre) like upper(:strNombre) " +
                    " and upper(u.cvApellidopaterno) like upper(:strApellidopaterno) " +
                    " and upper(u.cvApellidomaterno) like upper(:strApellidomaterno)" +
                    "and upper(u.cvIdusuario) like upper(:strUsuario)";
//            if (objUsuario.getSrlIdpersona() != 0) {
//                hql += " and u.srlIdpersona= :idUsuario ";
//            }
            if ((objUsuario.isBoolBloqueado()) == true) {//si solo se desea listar los roles bloqueados
                hql += " and a.boolBloqueado = :boolUsuarioBloqueado";
            }
            if ((objUsuario.isBoolEliminado()) == true) {//si solo se desea listar los roles eliminados
                hql += " and a.boolEliminado = :boolUsuarioEliminado";
            }
            Query query = (Query) session.createQuery(hql);
            //indico que si algun campo es NULL, lo reemplaze por '%%' para el LIKE (recordar SQL)
            String strNombre = ((objUsuario.getCvNombre() == null) ? "%%" : "%" + objUsuario.getCvNombre() + "%");
            String strApellidopaterno = ((objUsuario.getCvApellidopaterno() == null) ? "%%" : "%" + objUsuario.getCvApellidopaterno() + "%");
            String strApellidomaterno = ((objUsuario.getCvApellidomaterno() == null) ? "%%" : "%" + objUsuario.getCvApellidomaterno() + "%");
            String strUsuario = ((objUsuario.getCvIdusuario()== null) ? "%%" : "%" + objUsuario.getCvIdusuario() + "%");
            query.setString("strNombre", strNombre);
            query.setString("strUsuario", strUsuario);
            query.setString("strApellidopaterno", strApellidopaterno);
            query.setString("strApellidomaterno", strApellidomaterno);
//            if (objUsuario.getSrlIdpersona() != 0) {
//                query.setInteger("idUsuario", objUsuario.getSrlIdpersona());
//            }
            if ((objUsuario.isBoolBloqueado()) == true) {
                query.setBoolean("boolUsuarioBloqueado", objUsuario.isBoolBloqueado());
            }
            if ((objUsuario.isBoolEliminado()) == true) {
                query.setBoolean("boolUsuarioEliminado", objUsuario.isBoolEliminado());
            }



            session.flush();
//            lista = crit.list();
            lista = query.list();
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            if (tx != null && tx.isActive()) {
                tx.rollback();
            }
        }
        return lista;
    }

    public List<Usuario> buscarUsuario(Usuario objUsuario) {
        //System.out.println("el usuario a buscar es: " + objUsuario.getCvIdusuario());
        //System.out.println("la clave a buscar es: " + objUsuario.getCvContrasenha());
        List<Usuario> lista = new ArrayList<Usuario>();
        tx = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            tx = session.beginTransaction();
            String hql = "FROM Usuario as u"
                    + " WHERE u.cvIdusuario = :strIdusuario"
                    + " AND u.cvContrasenha = :strContrasenha";
            Query query = session.createQuery(hql);
            String strIdusuario = objUsuario.getCvIdusuario();
            String strContrasenha = objUsuario.getCvContrasenha();
            query.setString("strIdusuario", strIdusuario);
            query.setString("strContrasenha", Logica.hashDeCadena(strContrasenha));
            session.flush();
            lista = query.list();
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            if (tx != null && tx.isActive()) {
                tx.rollback();
            }
        }
        return lista;
    }

    /**
     * Buscar por el nombre de usario en el sistema
     * @param objUsuario
     * @return
     */
    public Usuario buscarUsuarioPorNombreUsuario(Usuario objUsuario) {
        List<Usuario> lista = new ArrayList<Usuario>();
        Transaction tx = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            tx = session.beginTransaction();
            String hql = "FROM Usuario as u WHERE u.cvIdusuario = :cvIdusuario";
            Query query = session.createQuery(hql);
            String cvIdusuario = objUsuario.getCvIdusuario();
            query.setString("cvIdusuario", cvIdusuario);
            session.flush();
            lista = query.list();
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            if (tx != null && tx.isActive()) {
                tx.rollback();
            }
        }
        if (lista.size() == 1) return lista.get(0);
        else return null;
    }

    public Usuario buscarUsuarioPorSrl(Usuario objUsuario) {
        List<Usuario> lista = new ArrayList<Usuario>();
        Transaction tx = null;
        System.out.println("buscando " + objUsuario.getSrlIdpersona());
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            tx = session.beginTransaction();
            String hql = "FROM Usuario as u WHERE u.srlIdpersona = :srlIdpersona";
            Query query = session.createQuery(hql);
            Integer srlIdpersona = objUsuario.getSrlIdpersona();
            query.setInteger("srlIdpersona", srlIdpersona);
            session.flush();
            lista = query.list();
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            if (tx != null && tx.isActive()) {
                tx.rollback();
            }
        }
        if (lista.size() == 1) return lista.get(0);
        else return null;
    }

    public Usuario buscarUsuarioPorCorreoPrimario(String strCorreo) {
        List<Usuario> lista = new ArrayList<Usuario>();
        Transaction tx = null;
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            tx = session.beginTransaction();
            String hql = "FROM Usuario as u WHERE u.cvEmail = :strCorreo";
            Query query = session.createQuery(hql);
            query.setString("strCorreo", strCorreo);
            session.flush();
            lista = query.list();
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            if (tx != null && tx.isActive()) {
                tx.rollback();
            }
        }
        if (lista.size() == 1) return lista.get(0);
        else return null;
    }

    public List<Usuario> buscarUsuarioInventario() {
        session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        List<Usuario> lista = null;
        try {
            String hql = "from Usuario as u where u.srlIdpersona not in (select ui.srlIdpersona from Usuarioinventario as ui where ui.boolActivo=true and ui.boolAsignado=true) order by u.cvNombre";
            Query query = session.createQuery(hql);
            session.flush();
            lista = query.list();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }
        return lista;
   }

	public List<Usuario> buscarUsuarioInventario(Usuario objUsuario){
        session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        List<Usuario> lista = null;
        try {
            String hql = "from Usuario as u " +
                    "where u.srlIdpersona in (select ui.srlIdpersona from Usuarioinventario as ui where ui.boolActivo=true) "; /*+
                         " order by u.cvNombre";*/

            String strNombre = "";
            String strApellidoPaterno = "";
            String strApellidoMaterno = "";
            String strDocumento = "";

            if (objUsuario.getSrlIdpersona() != -1) {
                hql += "and u.srlIdpersona = :srl_idpersona ";
            }

            if (objUsuario.getCvNombre() != null) {
                hql += "and upper(u.cvNombre) like upper(:cv_nombre) ";
                strNombre = objUsuario.getCvNombre();
            }

            if (objUsuario.getCvApellidopaterno() != null) {
                hql += "and upper(u.cvApellidopaterno) like upper(:cv_apepaterno) ";
                strApellidoPaterno = objUsuario.getCvApellidopaterno();
            }

            if (objUsuario.getCvApellidomaterno() != null) {
                hql += "and upper(u.cvApellidomaterno) like upper(:cv_apematerno) ";
                strApellidoMaterno = objUsuario.getCvApellidomaterno();
            }

            if (objUsuario.getSrlIdtipoidentificacion() != -1) {
                hql += "and u.srlIdtipoidentificacion = :srl_idtipoidentificacion ";
            }

            if (objUsuario.getCvDocumento() != null) {
                hql += "and upper(u.cvDocumento) like upper(:cv_documento) ";
                strDocumento = objUsuario.getCvDocumento();
            }

            hql += " order by u.cvNombre";

            Query query = session.createQuery(hql);

            query.setString("cv_nombre", "%" + strNombre + "%");
            query.setString("cv_apepaterno", "%" + strApellidoPaterno + "%");
            query.setString("cv_apematerno", "%" + strApellidoMaterno + "%");
            query.setString("cv_documento", "%" + strDocumento + "%");

            if (objUsuario.getSrlIdpersona() != -1) {
                query.setInteger("srl_idpersona", objUsuario.getSrlIdpersona());
            }

            if (objUsuario.getSrlIdtipoidentificacion() != -1) {
                query.setInteger("srl_idtipoidentificacion", objUsuario.getSrlIdtipoidentificacion());
            }

            session.flush();
            lista = query.list();
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }
        return lista;
    }

    public List<Usuario> listaUsuarioInventario(int idAlmacen) {
        session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        List<Usuario> lista = null;
        try {
            String hql = "from Usuario as u where u.srlIdpersona in (select ui.srlIdpersona from Usuarioinventario as ui where ui.boolActivo=true";
            if(idAlmacen==-1){
             hql +=")";
            }else{
                hql +=" and srl_idalmacen= "+ idAlmacen+" )";
}
            hql += " order by u.cvNombre";

            Query query = session.createQuery(hql);
            session.flush();
            lista = query.list();
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }
       return lista;
    }

    public ArrayList<Funcionalidad> obtieneFuncionalidadesPermitidas(int srlIdpersona) {
        List<Object> listaSimple = new ArrayList<Object>();
        ArrayList<Funcionalidad> listaFuncionalidades = new ArrayList<Funcionalidad>();
        Transaction tx = null;

        try {
            // recabar informacion
            session = HibernateUtil.getSessionFactory().openSession();
            tx = session.beginTransaction();
            String hql = "SELECT f.srlIdfuncionalidad, f.cvNombre\n" +
                    "FROM Usuario as u, Usuarioxrol as uxr, Funcionalidadxrol as fxr, Funcionalidad as f\n" +
                    "WHERE\n" +
                    " u.srlIdpersona = uxr.usuario\n" +
                    " AND uxr.rol = fxr.rol\n" +
                    " AND f.srlIdfuncionalidad = fxr.funcionalidad\n" +
                    " AND u.srlIdpersona = :srlIdpersona\n";
            Query query = session.createQuery(hql);
            query.setInteger("srlIdpersona", srlIdpersona);
            session.flush();
            listaSimple = query.list();
            tx.commit();

            // organizar informacion
            Iterator it = listaSimple.iterator();
            Object[] linea;
            Funcionalidad objFuncionalidad;
            while (it.hasNext()) {
                linea = (Object[]) it.next();
                objFuncionalidad = new Funcionalidad(Integer.parseInt(linea[0].toString()), linea[1].toString());
                listaFuncionalidades.add(objFuncionalidad);
                objFuncionalidad = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (tx != null && tx.isActive()) {
                tx.rollback();
            }
        }
        return listaFuncionalidades;
    }

       public List<Usuario> buscarUsuarioVentas(Usuario objUsuario){

        List<Usuario> lista = null;
        try {
            session = HibernateUtil.getSessionFactory().getCurrentSession();
            Transaction tx = session.beginTransaction();
            Criteria crit = session.createCriteria(Usuario.class);
            session.flush();
            session.evict(objUsuario);
            if (objUsuario.getSrlIdpersona()> 0) {
                crit.add(Restrictions.eq("srlIdpersona",objUsuario.getSrlIdpersona()));
            }
            crit.add(Restrictions.eq("boolEliminado", false));
            session.flush();
            session.evict(objUsuario);
            session.clear();
            lista = crit.list();
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return lista;


    }
       public List<Usuarioventas> buscarUsuarioDeVentas(Usuario objUsuario){

        List<Usuarioventas> lista = null;
        try {
            session = HibernateUtil.getSessionFactory().getCurrentSession();
            Transaction tx = session.beginTransaction();
            Criteria crit = session.createCriteria(Usuarioventas.class);
            session.flush();
            session.evict(objUsuario);
            if (objUsuario.getSrlIdpersona()> 0) {
                crit.add(Restrictions.eq("srlIdpersona",objUsuario.getSrlIdpersona()));
            }
            crit.add(Restrictions.eq("boolFlagvendedor", true));
            session.flush();
            session.evict(objUsuario);
            session.clear();
            lista = crit.list();
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return lista;
    }


            public int obtieneId(Usuario objUsuarioSolicitanteBE) {
        session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        List<Usuario> lista = null;
        try {
            String hql = "from Usuario as u where upper(u.cvNombre) like upper(:strNombre)";

            hql += " order by u.cvNombre";

            Query query = session.createQuery(hql);
            String strNombre = ((objUsuarioSolicitanteBE.getCvNombre() == null) ? "%%" : "%" + objUsuarioSolicitanteBE.getCvNombre() + "%");
            query.setString("strNombre", strNombre);
            session.flush();
            lista = query.list();
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }
        if (lista.size() > 0) {
            return lista.get(0).getSrlIdpersona();
        } else {
            return -1;
        }
    }

    public boolean cambiarClave(Usuario objUsuario) {
        try {
            session = HibernateUtil.getSessionFactory().openSession();
            tx = session.beginTransaction();
            Usuario objUsuarioX = (Usuario) session.get(Usuario.class, new Integer(objUsuario.getSrlIdpersona()));
            System.out.println("trando de poner " + objUsuario.getCvContrasenha() + " en uid " + objUsuario.getSrlIdpersona());
            objUsuarioX.setCvContrasenha(objUsuario.getCvContrasenha());
            session.update(objUsuarioX);
            tx.commit();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
                if (tx != null && tx.isActive()) {
                tx.rollback();
            }
            return false;
        }
    }


}
